import { Init, Provide, Inject, App } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { LessThan, Repository } from 'typeorm';
import { GameRoomInfoEntity } from '../entity/room';
import * as _ from 'lodash';
import { Action, RoomQueue } from '../queue/room';
import { BaseSysParamService } from '../../base/service/sys/param';
import { CsConnService } from "../service/conn"
import { GameLevelInfoService } from '../service/info';
import { v1 as uuid } from 'uuid';
import { BaseSysConfService } from '../../base/service/sys/conf';
import moment = require('moment');

/**
 * game模块-房间信息
 */
@Provide()
export class GameRoomInfoService extends BaseService {
    @InjectEntityModel(GameRoomInfoEntity)
    gameRoomInfoEntity: Repository<GameRoomInfoEntity>;

    @Inject()
    ctx;

    @Inject()
    roomQueue: RoomQueue;

    @Inject()
    baseSysParamService: BaseSysParamService;

    @Inject()
    gameLevelInfoService: GameLevelInfoService;

    @Inject()
    csConnService: CsConnService;

    @Inject()
    BaseSysConfService: BaseSysConfService


    @Init()
    async init() {
        await super.init();
        this.setEntity(this.gameRoomInfoEntity);
    }

    /**
     * 创建房间
     * @param param
     * @returns
     */
    async add() {
        let param = {
            roomNumber: _.random(100000, 999999),
            ownerId: this.ctx.user.id
        }
        const roomTimeout = await this.baseSysParamService.dataByKey(
            'roomTimeout'
        );
        // 调用原本的add
        const result = await this.gameRoomInfoEntity.save(param);
        // 创建房间创建消息
        this.roomQueue.add(
            { result, action: Action.TIMEOUT },
            {
                // 超时解散房间
                delay: roomTimeout * 60 * 1000,
            }
        );
        let item = await this.nativeQuery(
            'SELECT a.*,b.avatarUrl as ownerAvatar,b.nickName as ownerNickname, c.avatarUrl as memberAvatar, c.nickName as memberNickname FROM game_room_info a  LEFT JOIN user_info b ON a.ownerId = b.id LEFT JOIN user_info c ON a.memberId = c.id WHERE a.id = (?) LIMIT 1 ',
            [result.id]
        );
        // 你自己的业务逻辑
        return { ...item[0], roomNumber: param.roomNumber };
    }

    /**
    * 房间详情
    * @param param
    * @returns
    */
    async info(param) {
        console.log(param)
        // let param = {
        //     roomNumber: _.random(100000, 999999),
        //     ownerId: this.ctx.user.id
        // }
        let item = await this.nativeQuery(
            'SELECT a.*,b.avatarUrl as ownerAvatar,b.nickName as ownerNickname, c.avatarUrl as memberAvatar, c.nickName as memberNickname FROM game_room_info a  LEFT JOIN user_info b ON a.ownerId = b.id LEFT JOIN user_info c ON a.memberId = c.id WHERE a.id = (?) LIMIT 1 ',
            [param]
        );
        // 你自己的业务逻辑
        return { ...item[0]};
    }
    /**
     * 选择关卡
     * @param param
     * @returns
     */
    async selectLevel(id: number) {
        const detail = await this.gameRoomInfoEntity.findOneBy({ id })
        if (!detail.memberId) {
            throw new CoolCommException('房间人数不足');
        }
        if (detail.ownerReady == 0 || detail.memberReady == 0) {
            throw new CoolCommException('检测到有成员未准备');
        }
        const list = await this.gameLevelInfoService.getLevels()
        this.csConnService.sendMessage(detail.memberId, {
            type: "selectLevel",
            content: {
                roomId: id,
                list
            }
        })
        return list
    }

    /**
     * 修改准备状态
     * @param param
     * @returns
     */
    async changeReady(param: any) {
        let { id, type, ...item } = param
        let detail = await this.gameRoomInfoEntity.findOneBy({ id })
        if (detail.status != 0) {
            throw new CoolCommException('房间已开始或已解散');
        }
        await this.gameRoomInfoEntity.update(
            { id: id },
            { ...item }
        );
        // 0的话代表修改状态的是房主,给成员发
        // 1的话代表修改状态的是成员,给房主发
        this.csConnService.sendMessage(type == 1 ? detail.ownerId : detail.memberId, {
            type: "changeReady",
            content: { ...param, roomId: id }
        })
    }

    /**
     * 解散房间
     * @param id
     * @returns
     */
    async dissolveRoom(id: number) {
        let detail = await this.gameRoomInfoEntity.findOneBy({ id })
        if (detail.status == 2) {
            throw new CoolCommException('当前房间已解散,请勿重复解散');
        }
        if (detail.status == 1) {
            throw new CoolCommException('游戏已开始');
        }
        let status = [{ label: "未开始", value: 0 }, { label: "已开始", value: 1 }]
        let label = status.find(item => item.value == detail.status)?.label
        if (detail.ownerId == this.ctx.user?.id) {
            await this.gameRoomInfoEntity.update({ id }, { status: 2, remark: `${label},主动解散房间` });
        } else {
            throw new CoolCommException('只有房主可以解散房间');
        }
        // 房主解散房间，给成员发消息
        this.csConnService.sendMessage(detail.memberId, {
            type: "dissolveRoom",
            content: { ...detail, roomId: detail.id }
        })
    }

    /**
     * 加入房间
     * @param roomNumber
     * @returns
     */
    async joinRoom(roomNumber: string) {
        let detail = await this.gameRoomInfoEntity.findOneBy({ roomNumber })
        if (!detail) {
            throw new CoolCommException('房间不存在');
        }
        // if (detail.memberId == this.ctx.user.id) {
        //     let item = await this.nativeQuery(
        //         'SELECT a.*,b.avatarUrl as ownerAvatar,b.nickName as ownerNickname, c.avatarUrl as memberAvatar, c.nickName as memberNickname FROM game_room_info a LEFT JOIN user_info b ON a.ownerId = b.id LEFT JOIN user_info c ON a.memberId = c.id WHERE a.id = (?)',
        //         [detail.id]
        //     );
        //     // 成员加入房间，给房主发消息
        //     this.csConnService.sendMessage(detail.ownerId, {
        //         type: "joinRoom",
        //         content: { ...item[0], roomId: item[0].id }
        //     })
        //     return item[0]
        // } else {
            if (detail.memberId) {
                throw new CoolCommException('当前房间已满员');
            }
            if (detail.status == 2) {
                throw new CoolCommException('当前房间已解散');
            }
            if (this.ctx.user.id == detail.ownerId) {
                throw new CoolCommException('参数不合法');
            }
            await this.gameRoomInfoEntity.update({ roomNumber }, { memberId: this.ctx.user.id });
            let item = await this.nativeQuery(
                'SELECT a.*,b.avatarUrl as ownerAvatar,b.nickName as ownerNickname, c.avatarUrl as memberAvatar, c.nickName as memberNickname FROM game_room_info a LEFT JOIN user_info b ON a.ownerId = b.id LEFT JOIN user_info c ON a.memberId = c.id WHERE a.id = (?)',
                [detail.id]
            );
            // 成员加入房间，给房主发消息
            this.csConnService.sendMessage(detail.ownerId, {
                type: "joinRoom",
                content: { ...item[0], roomId: item[0].id }
            })
            return item[0]
        // }

    }

    /**
     * 离开房间
     * @param roomNumber
     * @returns
     */
    async leaveRoom(roomNumber: string) {
        let detail = await this.gameRoomInfoEntity.findOneBy({ roomNumber })
        if (detail.memberId == this.ctx.user?.id) {
            await this.gameRoomInfoEntity.update({ roomNumber }, { memberId: "", memberReady: 0 });
        } else {
            throw new CoolCommException('您不在当前房间内');
        }
        if (detail.status == 1) {
            throw new CoolCommException('游戏已开始');
        }
        // 成员离开房间,给房主发消息
        this.csConnService.sendMessage(detail.ownerId, {
            type: "leaveRoom",
            content: { ...detail, roomId: detail.id }
        })
    }

    /**
     * 超时未开始解散房间
     * @param roomNumber
     * @returns
     */
    async close(id, remark) {
        let detail = await this.gameRoomInfoEntity.findOneBy({ id })
        // 已经开始
        if (detail.status == 1) {
            throw new CoolCommException('游戏已经开始');
        }
        if (detail.status == 2) {
            throw new CoolCommException('房间已经解散');
        }
        await this.gameRoomInfoEntity.update(
            { id },
            { status: 2, remark }
        );
        // 给双方发消息
        this.csConnService.sendMessage(detail.ownerId, {
            type: "clear",
            content: { ...detail, roomId: detail.id }
        })
        this.csConnService.sendMessage(detail.memberId, {
            type: "clear",
            content: { ...detail, roomId: detail.id }
        })
    }
    /**
     * 清除房间记录
     */
    async clear() {
        const keepDay = await this.BaseSysConfService.getValue('roomKeep');
        if (keepDay) {
            const beforeDate = moment().add(-keepDay, 'days').startOf('day').toDate();
            await this.gameRoomInfoEntity.delete({ updateTime: LessThan(beforeDate) });
        }
    }
}
